package com.leilei.serviceProject.domain.strategy.service.rule.tree.factory.engine.impl;

import com.leilei.serviceProject.domain.strategy.model.valobj.RaffleResultCheckVo;
import com.leilei.serviceProject.domain.strategy.model.valobj.RuleTreeNodeLineVo;
import com.leilei.serviceProject.domain.strategy.model.valobj.RuleTreeNodeVo;
import com.leilei.serviceProject.domain.strategy.model.valobj.RuleTreeVo;
import com.leilei.serviceProject.domain.strategy.service.rule.tree.ILogicTreeNode;
import com.leilei.serviceProject.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import com.leilei.serviceProject.domain.strategy.service.rule.tree.factory.engine.IRuleTreeEngine;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

/**
 * @author yanglei
 * @description 规则树引擎，通过规则树节点匹配对应的逻辑树节点执行
 * @create 2024/11/19 17:13
 */
@AllArgsConstructor
@NoArgsConstructor
public class RuleTreeEngine implements IRuleTreeEngine {
    private Map<String, ILogicTreeNode> logicTreeNodeGroup;
    private RuleTreeVo ruleTree;

    @Override
    public DefaultTreeFactory.TreeResultData process(Long strategyId, String userId, Integer awardId) {
        // 所有节点
        Map<String, RuleTreeNodeVo> treeNodeMap = ruleTree.getTreeNodeMap();
        // 根节点
        String nextNode = ruleTree.getRootNode();
        RuleTreeNodeVo treeNodeVo = treeNodeMap.get(nextNode);
        String ruleValue = treeNodeVo.getRuleValue();

        DefaultTreeFactory.TreeResultData resultData = null;
        while (null != nextNode) {
            // 获取逻辑树节点执行
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(treeNodeVo.getRuleKey());
            DefaultTreeFactory.TreeLogicResultEntity treeLogicResult = logicTreeNode.logic(strategyId, userId, awardId, ruleValue);
            RaffleResultCheckVo ruleTreeResultCheck = treeLogicResult.getRuleTreeResultCheck();
            resultData = treeLogicResult.getTreeResultData();

            // 执行结果判断：是否还需下个逻辑树节点执行
            nextNode = nextNode(ruleTreeResultCheck.getCode(), treeNodeVo.getTreeNodeLinkList());
            treeNodeVo = treeNodeMap.get(nextNode);
        }

        return resultData;
    }

    private String nextNode(String treeResultCheckCode, List<RuleTreeNodeLineVo> treeNodeLinkList) {
        if (null == treeNodeLinkList || treeNodeLinkList.isEmpty()) {
            return null;
        }

        for (RuleTreeNodeLineVo treeNodeLink : treeNodeLinkList) {
            if (decisionLogic(treeResultCheckCode, treeNodeLink)) {
                return treeNodeLink.getToTreeNode();
            }
        }
        //throw new RuntimeException("决策树引擎，nextNode 计算失败，未找到可执行节点！");
        return null;
    }

    private boolean decisionLogic(String treeResultCheckCode, RuleTreeNodeLineVo treeNodeLink) {
        switch (treeNodeLink.getRuleLimitType()) {
            case EQUAL:
                return treeResultCheckCode.equals(treeNodeLink.getRuleLimitValue().getCode());
            // 以下规则暂时不需要实现
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }
}
